# coding=utf-8

import asyncio
import os
from typing import Optional, Dict, Any

import dashscope
from dashscope.api_entities.dashscope_response import SpeechSynthesisResponse
from dashscope.audio.tts import ResultCallback, SpeechSynthesizer, SpeechSynthesisResult
from dotenv import load_dotenv

from config.logging_config import get_logger

# 加载环境变量
load_dotenv()

# 配置日志
logger = get_logger(__name__)

# DashScope 配置
if not dashscope.api_key:
    dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")

if not dashscope.api_key:
    logger.warning("DashScope API Key 未配置，TTS功能将无法使用")


class TTSCallback(ResultCallback):
    """TTS 回调处理类"""

    def __init__(self, on_audio_chunk=None, on_complete=None, on_error=None):
        self.on_audio_chunk = on_audio_chunk
        self.on_complete_callback = on_complete
        self.on_error_callback = on_error
        self.audio_chunks = []
        self.total_audio_data = b''

    def on_open(self):
        logger.info('TTS 语音合成器已打开')

    def on_complete(self):
        logger.info('TTS 语音合成完成')
        if self.on_complete_callback:
            self.on_complete_callback(self.total_audio_data)

    def on_error(self, response: SpeechSynthesisResponse):
        error_msg = f'TTS 语音合成失败: {str(response)}'
        logger.error(error_msg)
        if self.on_error_callback:
            self.on_error_callback(error_msg)

    def on_close(self):
        logger.info('TTS 语音合成器已关闭')

    def on_event(self, result: SpeechSynthesisResult):
        # 处理音频数据
        if result.get_audio_frame() is not None:
            audio_chunk = result.get_audio_frame()
            self.audio_chunks.append(audio_chunk)
            self.total_audio_data += audio_chunk

            # 如果有流式回调，立即处理音频块
            if self.on_audio_chunk:
                self.on_audio_chunk(audio_chunk)

            logger.debug(f'收到音频块，大小: {len(audio_chunk)} 字节')

        # 处理时间戳信息
        if result.get_timestamp() is not None:
            logger.debug(f'时间戳信息: {str(result.get_timestamp())}')


class TTSManager:
    """TTS 管理器"""

    def __init__(self):
        self.default_config = {
            'model': 'sambert-zhijia-v1',  # 默认使用
            'sample_rate': 48000,
            'format': 'wav',
            'volume': 50,
            'speech_rate': 1.0,
            'pitch_rate': 1.0
        }

    def synthesize_sync(self, text: str, config: Optional[Dict[str, Any]] = None) -> Optional[bytes]:
        """
        同步语音合成
        适合短文本，一次性返回完整音频数据
        """
        if not dashscope.api_key:
            logger.error("DashScope API Key 未配置")
            return None

        # 合并配置
        tts_config = {**self.default_config}
        if config:
            tts_config.update(config)

        try:
            logger.info(f"开始同步TTS合成: {text[:50]}...")

            result = SpeechSynthesizer.call(
                model=tts_config['model'],
                text=text,
                sample_rate=tts_config['sample_rate'],
                format=tts_config['format'],
                volume=tts_config.get('volume', 50),
                rate=tts_config.get('speech_rate', 1.0),
                pitch=tts_config.get('pitch_rate', 1.0)
            )

            if result.get_audio_data() is not None:
                audio_data = result.get_audio_data()
                logger.info(f'TTS合成成功，音频大小: {len(audio_data)} 字节')
                return audio_data
            else:
                logger.error(f'TTS合成失败: {result.get_response()}')
                return None

        except Exception as e:
            logger.error(f'TTS合成异常: {str(e)}')
            return None

    async def synthesize_async(self, text: str, config: Optional[Dict[str, Any]] = None) -> Optional[bytes]:
        """
        异步语音合成
        """
        return await asyncio.get_event_loop().run_in_executor(
            None, self.synthesize_sync, text, config
        )

    def synthesize_streaming(self, text: str, on_audio_chunk, on_complete, on_error,
                             config: Optional[Dict[str, Any]] = None):
        """
        流式语音合成
        适合长文本，实时返回音频块
        """
        if not dashscope.api_key:
            logger.error("DashScope API Key 未配置")
            on_error("DashScope API Key 未配置")
            return

        # 合并配置
        tts_config = {**self.default_config}
        if config:
            tts_config.update(config)

        try:
            logger.info(f"开始流式TTS合成: {text[:50]}...")

            callback = TTSCallback(
                on_audio_chunk=on_audio_chunk,
                on_complete=on_complete,
                on_error=on_error
            )

            SpeechSynthesizer.call(
                model=tts_config['model'],
                text=text,
                sample_rate=tts_config['sample_rate'],
                format=tts_config['format'],
                callback=callback,
                volume=tts_config.get('volume', 50),
                speech_rate=tts_config.get('speech_rate', 1.0),
                pitch_rate=tts_config.get('pitch_rate', 1.0),
                word_timestamp_enabled=True,  # 启用词级时间戳
                phoneme_timestamp_enabled=True  # 启用音素级时间戳
            )

        except Exception as e:
            error_msg = f'流式TTS合成异常: {str(e)}'
            logger.error(error_msg)
            on_error(error_msg)

    def get_available_models(self):
        """获取可用的TTS模型列表"""
        return [
            {
                'model': 'sambert-zhichu-v1',
                'name': '知厨',
                'language': 'zh-CN',
                'description': '舌尖男声'
            },
            {
                'model': 'sambert-zhijia-v1',
                'name': '知佳',
                'language': 'zh-CN',
                'description': '标准女声'
            },
            {
                'model': 'sambert-zhiyue-v1',
                'name': '知悦',
                'language': 'zh-CN',
                'description': '温柔女声'
            },
            {
                'model': 'sambert-eva-v1',
                'name': 'Eva',
                'language': 'zh-CN',
                'description': '陪伴女声'
            }
        ]


# 全局TTS管理器实例
tts_manager = TTSManager()

# 确保模块被导入时正确初始化
logger.info("TTS管理器已初始化")
